/*
 * Copyright (c) 2020. www.sonsure.com Inc. All rights reserved.
 * You may obtain more information at
 *
 *   http://www.sonsure.com
 *
 * Designed By Selfly Lee (selfly@live.com)
 */

package com.sonsure.dustman.jdbc.persist;

import com.sonsure.dustman.common.model.Page;
import com.sonsure.dustman.common.model.Pageable;
import com.sonsure.dustman.jdbc.command.CommandExecutor;
import com.sonsure.dustman.jdbc.command.batch.BatchUpdateExecutor;
import com.sonsure.dustman.jdbc.command.batch.ParameterizedSetter;
import com.sonsure.dustman.jdbc.command.entity.Delete;
import com.sonsure.dustman.jdbc.command.entity.Insert;
import com.sonsure.dustman.jdbc.command.entity.Select;
import com.sonsure.dustman.jdbc.command.entity.Update;
import com.sonsure.dustman.jdbc.command.mybatis.MybatisExecutor;
import com.sonsure.dustman.jdbc.command.natives.NativeExecutor;
import com.sonsure.dustman.jdbc.config.JdbcContext;

import java.io.Serializable;
import java.sql.Connection;
import java.util.Collection;
import java.util.List;

/**
 * @author liyd
 * @since 17/4/12
 */
public interface JdbcDao {

    /**
     * 指定使用的持久化jdbc对象
     *
     * @param name the name
     * @return jdbc dao
     */
    JdbcDao use(String name);

    /**
     * 获取一个实体对象
     *
     * @param <T>         the type parameter
     * @param entityClass the entity class
     * @param id          the id
     * @return t t
     */
    <T> T get(Class<T> entityClass, Serializable id);

    /**
     * 查询所有列表
     *
     * @param <T>         the type parameter
     * @param entityClass the entity class
     * @return list
     */
    <T> List<T> findAll(Class<T> entityClass);

    /**
     * 根据实体条件查询列表,根据默认主键desc排序
     *
     * @param <T>    the type parameter
     * @param entity the entity
     * @return list
     */
    <T> List<T> findList(T entity);

    /**
     * 根据实体条件查询记录数
     *
     * @param cls the cls
     * @return long
     */
    long findAllCount(Class<?> cls);

    /**
     * 根据实体条件查询记录数
     *
     * @param entity the entity
     * @return long
     */
    long findCount(Object entity);

    /**
     * 查询分页列表
     *
     * @param <T>    the type parameter
     * @param entity the entity
     * @return page
     */
    <T extends Pageable> Page<T> findPage(T entity);

    /**
     * 根据实体条件查询单个结果
     *
     * @param <T>    the type parameter
     * @param entity the entity
     * @return t
     */
    <T> T findOne(T entity);

    /**
     * 根据实体条件查询首个结果
     *
     * @param <T>    the type parameter
     * @param entity the entity
     * @return t
     */
    <T> T findFirst(T entity);

    /**
     * 插入
     *
     * @param <T>    the type parameter
     * @param <R>    the type parameter
     * @param entity the entity
     * @return object r
     */
    <T, R> R executeInsert(T entity);

    /**
     * 创建insert对象
     *
     * @param cls the cls
     * @return insert
     */
    Insert insertInto(Class<?> cls);

    /**
     * 删除
     *
     * @param entityClass the entity class
     * @param id          the id
     * @return int
     */
    int executeDelete(Class<?> entityClass, Serializable id);

    /**
     * 根据实体条件删除
     *
     * @param entity the entity
     * @return int int
     */
    int executeDelete(Object entity);

    /**
     * 删除所有对象
     *
     * @param cls the cls
     * @return int int
     */
    int executeDeleteAll(Class<?> cls);

    /**
     * 更新
     *
     * @param entity the entity
     * @return int
     */
    int executeUpdate(Object entity);

    /**
     * 创建update对象
     *
     * @param cls the cls
     * @return update
     */
    Update update(Class<?> cls);

    /**
     * 创建select对象
     *
     * @param <M> the type parameter
     * @param cls the cls
     * @return select select
     */
    <M> Select<M> selectFrom(Class<M> cls);

    /**
     * 创建insert对象
     *
     * @return insert insert
     */
    Insert insert();

    /**
     * 创建delete对象
     *
     * @return delete
     */
    Delete delete();

    /**
     * 创建delete对象
     *
     * @param cls the cls
     * @return delete delete
     */
    Delete deleteFrom(Class<?> cls);

    /**
     * 创建update对象
     *
     * @return update update
     */
    Update update();

    /**
     * Batch update.
     *
     * @param <T>                 the type parameter
     * @param <R>                 the type parameter
     * @param command             the command
     * @param batchData           the batch data
     * @param batchSize           the batch size
     * @param parameterizedSetter the parameterized setter
     * @return the object
     */
    <T,R> R executeBatchUpdate(String command, Collection<T> batchData, int batchSize, ParameterizedSetter<T> parameterizedSetter);

    /**
     * 执行脚本
     *
     * @param script the script
     */
    void executeScript(String script);

    /**
     * Execute in connection t.
     *
     * @param <T>       the type parameter
     * @param execution the execution
     * @return the t
     */
    <T> T executeInConnection(ExecutionFunction<Connection, T> execution);

    /**
     * Execute in raw t.
     *
     * @param execution the execution
     * @return the t
     */
    Object executeInRaw(ExecutionFunction<Object, Object> execution);

    /**
     * Batch update batch update executor.
     *
     * @return the batch update executor
     */
    BatchUpdateExecutor batchUpdate();

    /**
     * 创建native executor对象
     *
     * @return native executor
     */
    NativeExecutor nativeExecutor();

    /**
     * 创建mybatis executor对象
     *
     * @return mybatis executor
     */
    MybatisExecutor myBatisExecutor();

    /**
     * 创建自定义executor
     *
     * @param <T>      the type parameter
     * @param executor the executor
     * @param params   the params
     * @return t t
     */
    <T extends CommandExecutor<?>> T createExecutor(Class<T> executor, Object... params);

    /**
     * Gets jdbc context.
     *
     * @return the jdbc context
     */
    JdbcContext getJdbcContext();
}
